package com.suncky.frame.base.adapter;

import android.content.Context;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.suncky.frame.base.adapter.holder.RecyclerViewBindingHolder;
import com.suncky.frame.base.adapter.holder.RecyclerViewHolder;
import com.suncky.frame.base.adapter.listener.OnItemClickListener;
import com.suncky.frame.base.adapter.listener.OnItemLongClickListener;
import com.suncky.frame.base.adapter.listener.RecyclerAdapterListener;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * Created by HY_PC on 2019 2/11 0011 17:57.
 */
public abstract class RecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerViewHolder> implements RecyclerViewHolder.SubViewEventListener {
    protected Context mContext;
    protected List<T> mDatas;
    protected final int mItemLayoutId;
    protected RecyclerAdapterListener mListener;
    protected OnItemClickListener itemClickListener;
    protected OnItemLongClickListener itemLongClickListener;
    protected int mMarkedPosition = -1;//标记位置
    private final SparseArray<RecyclerViewHolder> holderArray = new SparseArray<>();//保存ViewHolder和position的对应关系

    public RecyclerViewAdapter(Context context){
        this(context, null);
    }
    public RecyclerViewAdapter(Context context, List<T> data){
        this(context, data, 0);
    }
    public RecyclerViewAdapter(Context context, List<T> data, int itemLayoutId){
        this(context, data, itemLayoutId,null);
    }
    public RecyclerViewAdapter(Context context, List<T> data, int itemLayoutId, RecyclerAdapterListener listener){
        this.mContext = context;
        this.mDatas = data;
        this.mItemLayoutId = itemLayoutId;
        this.mListener = listener;
    }
    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new RecyclerViewHolder(parent,getItemLayoutId(viewType),this);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
        convert(holder, getItem(position), position);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position, @NonNull List<Object> payloads) {
        holderArray.put(position, holder);
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        } else {
            convert(holder, getItem(position), position, payloads);
        }
    }

    /**
     * 绑定数据(全量绑定)
     * @param holder ViewHolder
     * @param item 数据
     * @param position 位置
     */
    public abstract void convert(RecyclerViewHolder holder, T item, int position);

    /**
     * 绑定数据(可局部绑定)
     * @param holder ViewHolder
     * @param item 数据
     * @param position 位置
     * @param payloads 来自 {@link #notifyItemChanged(int, Object)} 或 {@link #notifyItemRangeChanged(int, int, Object)} 中的payload参数组成的数组。
     *                 如果payloads数组不为空,会自动调用此方法进行数据绑定,可使用payloads中的数据进行局部刷新.
     *                 如果payloads数组为空,会自动调用 {@link #convert(RecyclerViewHolder, Object, int)} 方法进行数据全量绑定
     */
    public void convert(RecyclerViewHolder holder, T item, int position, @NonNull List<Object> payloads){

    }

    @Override
    public int getItemCount() {
        return mDatas != null ? mDatas.size() : 0;
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    /**
     * 获取item布局id
     * @param viewType viewType return by {@link #getItemViewType(int)}
     * @return
     */
    public int getItemLayoutId(int viewType) {
        return mItemLayoutId;
    }

    /**
     * 获取标记位置
     * @return
     */
    public int getMarkedPosition() {
        return mMarkedPosition;
    }

    /**
     * 获取标记位置
     * @param position
     */
    public void setMarkedPosition(int position) {
        this.mMarkedPosition = position;
    }

    /**
     * 获取标记位置下的数据
     * @return
     */
    public T getMarkedPositionItem(){
        return getItem(mMarkedPosition);
    }

    /**
     * 刷新标记位置
     * @param position
     */
    public void refresh(int position) {
        if (mDatas == null || position < 0 || position > mDatas.size() - 1) {
            return;
        }
        if (mMarkedPosition >= 0) {
            notifyItemChanged(mMarkedPosition);
        }
        mMarkedPosition = position;
        notifyItemChanged(position);
    }

    /**
     * 设置数据源
     * @param data
     */
    public void setData(List<T> data) {
        if (mDatas == null || mDatas != data) {
            mDatas = data;
        }
        notifyDataSetChanged();
    }

    /**
     * 设置数据源及标记位置
     * @param data
     */
    public void setData(List<T> data, int position) {
        mDatas = data;
        mMarkedPosition = position;
        notifyDataSetChanged();
    }

    /**
     * 在末尾添加加数据
     * @param data
     */
    public void appendData(List<T> data){
        if (data == null || data.size() == 0) {
            return;
        }
        if (mDatas == null) {
            mDatas = new ArrayList<>();
        }
        int startPosition = mDatas.size();
        mDatas.addAll(data);
        notifyItemRangeInserted(startPosition, data.size());
    }

    /**
     * 在末尾添加加数据
     * @param data
     */
    public void appendData(T data){
        if (data == null) {
            return;
        }
        if (mDatas == null) {
            mDatas = new ArrayList<>();
        }
        int startPosition = mDatas.size();
        mDatas.add(data);
        notifyItemRangeInserted(startPosition, 1);
    }

    /**
     * 插入数据列表
     * @param position 插入位置
     * @param datas 数据列表
     */
    public void insertData(int position, List<T> datas) {
        if (position < 0 || position > getItemCount() || datas == null || datas.size() == 0) {
            return;
        }
        if (mDatas == null) {
            mDatas = new ArrayList<>();
        }
        mDatas.addAll(position, datas);
        notifyItemRangeInserted(position, datas.size());
    }

    /**
     * 插入数据
     * @param position 插入位置
     * @param data 数据
     */
    public void insertData(int position, T data) {
        if (data == null || position < 0 || position > getItemCount()) {
            return;
        }
        if (mDatas == null) {
            mDatas = new ArrayList<>();
        }
        mDatas.add(position, data);
        notifyItemRangeInserted(position, 1);
    }

    /**
     * 移除数据
     * @param position
     */
    public void remove(int position) {
        if (mDatas == null || position < 0 || position > mDatas.size() - 1) {
            return;
        }
        mDatas.remove(position);
        notifyItemRemoved(position);
    }

    /**
     * 移除数据,重新绑定数据
     * @param position
     */
    public void removeUpdate(int position) {
        if (mDatas == null || position < 0 || position > mDatas.size() - 1) {
            return;
        }
        mDatas.remove(position);
        notifyDataSetChanged();
    }


    /**
     * 清空数据源
     */
    public void clearData() {
        if (mDatas != null) {
            mDatas.clear();
        }
        notifyDataSetChanged();
    }

    public List<T> getData() {
        return mDatas;
    }

    public T getItem(int position) {
        if (mDatas == null || position < 0 || position > mDatas.size() - 1) {
            return null;
        }
        return mDatas.get(position);
    }

    public void setAdapterListener(RecyclerAdapterListener listener) {
        mListener = listener;
    }

    public void setOnItemClickListener(OnItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener itemLongClickListener) {
        this.itemLongClickListener = itemLongClickListener;
    }

    @Override
    public void onClick(View v, int position) {
        if (v == holderArray.get(position).itemView && itemClickListener != null) {
            itemClickListener.onItemClick(v, position);
            return;
        }
        if (mListener != null) {
            mListener.onClickEvent(position, v.getId());
        }
    }

    @Override
    public void onLongClick(View v, int position) {
        if (v == holderArray.get(position).itemView && itemLongClickListener != null) {
            itemLongClickListener.onItemLongClick(v, position);
            return;
        }
        if (mListener != null) {
            mListener.onLongClickEvent(position, v.getId());
        }
    }

    @Override
    public void onItemClick(View v, int position, int subPosition) {

    }
}
